#include "../../server/VirtualHost.hpp"
#include <google/protobuf/map.h>
#include <gtest/gtest.h>
#include <unordered_map>
#include <string>

micromq::VirtualHost::ptr host;

class VirtualHostTest : public testing::Environment
{
public:
    virtual void SetUp() override
    {
        host =std::make_shared<micromq::VirtualHost>("Host1", "./data", "./data/host1/meta.db");
        google::protobuf::Map<std::string, std::string> testMap;

        host->declareExchange("e1", micromq::ExchangeType::DIRECT, true, false, testMap);
        host->declareExchange("e2", micromq::ExchangeType::DIRECT, true, false, testMap);

        host->declareMsgQueue("q1", true, false, false, testMap);
        host->declareMsgQueue("q2", true, false, false, testMap);

        host->bind("e1", "q1", "news.music.e1.q1");
        host->bind("e1", "q2", "news.music.e1.q2");

        host->bind("e2", "q1", "news.music.e2.q1");
        host->bind("e2", "q2", "news.music.e2.q2");

        host->produceMessage("q1", nullptr, "hello-q1-1");
        host->produceMessage("q1", nullptr, "hello-q1-2");
        host->produceMessage("q1", nullptr, "hello-q1-3");

        host->produceMessage("q2", nullptr, "hello-q2-1");
        host->produceMessage("q2", nullptr, "hello-q2-2");
        host->produceMessage("q2", nullptr, "hello-q2-3");
    }

    virtual void TearDown() override
    {
        host->clear();
    }
};

TEST(host_test, consume_test)
{
    micromq::MessagePtr msg_q1 = host->consumeMessage("q1");
    ASSERT_EQ(msg_q1->payload().content(), std::string("hello-q1-1"));
    msg_q1 = host->consumeMessage("q1");
    ASSERT_EQ(msg_q1->payload().content(), std::string("hello-q1-2"));
    msg_q1 = host->consumeMessage("q1");
    ASSERT_EQ(msg_q1->payload().content(), std::string("hello-q1-3"));

    micromq::MessagePtr msg_q2 = host->consumeMessage("q2");
    ASSERT_EQ(msg_q2->payload().content(), std::string("hello-q2-1"));
    msg_q2 = host->consumeMessage("q2");
    ASSERT_EQ(msg_q2->payload().content(), std::string("hello-q2-2"));
    msg_q2 = host->consumeMessage("q2");
    ASSERT_EQ(msg_q2->payload().content(), std::string("hello-q2-3"));
}

TEST(host_test, remove_test)
{
    host->removeExchange("e1");
    host->removeExchange("e2");
    ASSERT_EQ(host->isExchangeExists("e1"), false);
    ASSERT_EQ(host->isExchangeExists("e2"), false);

    host->removeMsgQueue("q1");
    host->removeMsgQueue("q2");
    ASSERT_EQ(host->isMsgQueueExists("q1"), false);
    ASSERT_EQ(host->isMsgQueueExists("q2"), false);

    host->unbind("e1", "q1");
    host->unbind("e1", "q2");
    host->unbind("e2", "q1");
    host->unbind("e2", "q2");
    ASSERT_EQ(host->isBidingExists("e1", "q1"), false);
    ASSERT_EQ(host->isBidingExists("e1", "q2"), false);
    ASSERT_EQ(host->isBidingExists("e2", "q1"), false);
    ASSERT_EQ(host->isBidingExists("e2", "q2"), false);
}

int main(int argc, char* argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new VirtualHostTest);
    RUN_ALL_TESTS();

    return 0;
}